package org.aplikator.server.descriptor;

import org.aplikator.client.shared.descriptor.FunctionDTO;
import org.aplikator.client.shared.descriptor.FunctionWidgetDTO;
import org.aplikator.client.shared.descriptor.WidgetDTO;
import org.aplikator.server.Context;
import org.aplikator.server.function.Executable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Function extends ServerDescriptorBase implements Widget {
    
    
    /** selected wizards key */
    public static final String ANNOTATION_SELECTED_WIZARDS_KEY ="selected-wizard"; 
    
    private final Executable executable;

    private List<Property<? extends Serializable>> properties = new ArrayList<Property<? extends Serializable>>();
    
    private Map<String, WizardPage> wizards = new HashMap<String, WizardPage>();

    
    public Function(String id, String readableName, Executable executable) {
        super(id);
        setLocalizationKey(readableName);
        this.executable = executable;
        this.executable.setFunction(this);
    }
    

    public Executable getExecutable() {
        return executable;
    }

    public List<Property<? extends Serializable>> getProperties() {
        return properties;
    }

    public Function addProperty(Property<? extends Serializable> property) {
        properties.add(property);
        return this;
    }

    public FunctionDTO getFunctionDTO(Context ctx) {
        FunctionDTO functionDTO = new FunctionDTO(this.getId(), this.getLocalizedName(ctx));
        //functionDTO.setEnabled(isEnabled());
        functionDTO.setLocalizedName(this.getLocalizedName(ctx));
        for (Property<? extends Serializable> p : this.getProperties()) {
            functionDTO.addProperty(p.clientClone(ctx));
        }
//        Set<String> keySet = this.wizards.keySet();
//        for (String key : keySet) {
//            WizardPage wizard = this.wizards.get(key);
//            functionDTO.registerWizardPageDTO(key, wizard.getViewDTO(ctx));
//        }
     
        
        return functionDTO;
    }

    @Override
    public WidgetDTO getWidgetDescriptor(Context ctx) {
    	return new FunctionWidgetDTO(getFunctionDTO(ctx));
    }

    public void registerProperties(Form form) {
    }
    
    public void registerWizardPage(String wname, WizardPage wview) {
        this.wizards.put(wname, wview);
    }

    public void unregisterWizardPage(String wname) {
        this.wizards.remove(wname);
    }
    
    public WizardPage getRegistredView(String wname) {
        return this.wizards.get(wname);
    }

    
    private int size = -1;

    @Override
    public int getSize(){
        return size;
    }

    @Override
    public Widget setSize(int size){
        this.size = size;
        return this;
    }


    public void deregisterWizard(String wname) {
        this.wizards.remove(wname);
    }

    @Override
    public Widget setFormatPattern(String formatPattern) {
        return this;
    }

    @Override
    public String getFormatPattern() {
        return null;
    }

    private boolean enabled = true;

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public Widget setEnabled(boolean enabled) {
        this.enabled = enabled;
        return this;
    }

    @Override
    public Widget cloneWithReference(Reference<? extends Entity> referencingProperty){
        Function retval;
        try {
            retval = (Function) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new UnsupportedOperationException(e);
        }
        if (referencingProperty != null){
            retval.setEnabled(false);
        }
        return retval;
    }
}
